package com.anpy.bill.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.anpy.bill.model.Constants;
import com.anpy.bill.model.result.AccountLoginResult;
import com.anpy.bill.model.result.LoginResult;
import com.anpy.bill.utils.JWTUtil;
import com.anpy.common.service.utils.RedisUtils;
import com.personal.dao.entity.UserEntity;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: token 服务
 * @Author: anpy
 * @date: 2025/4/16 15:49
 */
@Slf4j
@Service
public class TokenService {

    private static final Integer TOKEN_EXPIRE_SECONDS = 60 * 60 * 24;

    /**
     * 生成 token
     *
     * @param user 登录用户信息
     * @return token
     */
    public String generateToken(UserEntity user) {
        Map<String, String> claims = new HashMap<>(4);
        LocalDateTime expireTime = LocalDateTime.now().plusSeconds(TOKEN_EXPIRE_SECONDS);
        claims.put("appId", "edu-analytics-manager");
        claims.put("endTime", expireTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        claims.put("userId", String.valueOf(user.getId()));

        RedisUtils.set(Constants.LOGIN_TOKEN_KEY + user.getId(),
                JSONUtil.toJsonStr(user),
                TOKEN_EXPIRE_SECONDS);

        try {
            return JWTUtil.createJWT(claims);
        } catch (ParseException e) {
            log.error("u751fu6210tokenu5931u8d25", e);
            throw new RuntimeException("u751fu6210 token u5931u8d25", e);
        }
    }

    /**
     * u9a8cu8bc1 token u5e76u83b7u53d6u7528u6237u4fe1u606f
     *
     * @param token JWT token
     * @return u7528u6237u4fe1u606fuff0cu5982u679ctokenu65e0u6548u5219u8fd4u56denull
     */
    public LoginResult validateTokenAndGetUser(String token) {
        if (StrUtil.isBlank(token)) {
            return null;
        }

        try {
            Claims claims = JWTUtil.parseJWT(token);
            String userId = claims.get("userId", String.class);
            if (StrUtil.isBlank(userId)) {
                return null;
            }

            String userJson = RedisUtils.get(Constants.LOGIN_TOKEN_KEY + userId);
            if (StrUtil.isBlank(userJson)) {
                return null;
            }

            return JSONUtil.toBean(userJson, LoginResult.class);
        } catch (Exception e) {
            log.error("token 失效", e);
            return null;
        }
    }

    /**
     * u5237u65b0 token u6709u6548u671f
     *
     * @param userId u7528u6237ID
     */
    public void refreshToken(String userId) {
        String userJson = RedisUtils.get(Constants.LOGIN_TOKEN_KEY + userId);
        if (StrUtil.isNotBlank(userJson)) {
            RedisUtils.set(Constants.LOGIN_TOKEN_KEY + userId, userJson, TOKEN_EXPIRE_SECONDS);
        }
    }

    /**
     * u6ce8u9500u767bu5f55
     *
     * @param userId u7528u6237ID
     */
    public void logout(String userId) {
        RedisUtils.delete(Constants.LOGIN_TOKEN_KEY + userId);
    }
}
